<?php

// 此处的 $db 是局部变量，要注意，它返回后在定义为全局变量，可以有多个实例。
function db_new($dbconf) {
	global $errno, $errstr;
	// 数据库初始化，这里并不会产生连接！
	if($dbconf) {
		//print_r($dbconf);
		// 代码不仅仅是给人看的，更重要的是给编译器分析的，不要玩 $db = new $dbclass()，那样不利于优化和 opcache 。
		switch ($dbconf['type']) {
			case 'mysql':      $db = new db_mysql($dbconf['mysql']); 		break;
            case 'mysqli':      $db = new db_mysqli($dbconf['mysqli']); 		break;
			case 'pdo_mysql':  $db = new db_pdo_mysql($dbconf['pdo_mysql']);	break;
			case 'pdo_sqlite': $db = new db_pdo_sqlite($dbconf['pdo_sqlite']);	break;
			case 'pdo_mongodb': $db = new db_pdo_mongodb($dbconf['pdo_mongodb']);	break;
			default: return xn_error(-1, 'Not suppported db type:'.$dbconf['type']);
		}
		if(!$db || ($db && $db->errstr)) {
			$errno = -1;
			$errstr = $db->errstr;
			return FALSE;
		}
		return $db;
	}
	return NULL;
}

// 测试连接
function db_connect($d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	
	$r = $d->connect();
	
	db_errno_errstr($r, $d);
	
	return $r;
}

function db_close($d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	$r = $d->close();
	
	db_errno_errstr($r, $d);
	
	return $r;
}

function db_sql_find_one($sql, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	$arr = $d->sql_find_one($sql);
	
	db_errno_errstr($arr, $d, $sql);
	
	return $arr;
}

function db_sql_find($sql, $key = NULL, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	$arr = $d->sql_find($sql, $key);
	
	db_errno_errstr($arr, $d, $sql);
	
	return $arr;
}

// 如果为 INSERT 或者 REPLACE，则返回 mysql_insert_id();
// 如果为 UPDATE 或者 DELETE，则返回 mysql_affected_rows();
// 对于非自增的表，INSERT 后，返回的一直是 0
// 判断是否执行成功: mysql_exec() === FALSE
function db_exec($sql, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	DEBUG AND xn_log($sql, 'db_exec');
	
	$n = $d->exec($sql);
	
	db_errno_errstr($n, $d, $sql);
	
	return $n;
}

function db_count($table, $cond = array(), $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$r = $d->count($d->tablepre.$table, $cond);
	
	db_errno_errstr($r, $d);
	
	return $r;
}

function db_maxid($table, $field, $cond = array(), $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$r = $d->maxid($d->tablepre.$table, $field, $cond);
	
	db_errno_errstr($r, $d);
	
	return $r;
}

// NO SQL 封装，可以支持 MySQL Marial PG MongoDB
function db_create($table, $arr, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	return db_insert($table, $arr);
}

function db_insert($table, $arr, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$sqladd = db_array_to_insert_sqladd($arr);
	if(!$sqladd) return FALSE;
	return db_exec("INSERT INTO {$d->tablepre}$table $sqladd", $d);
}

function db_replace($table, $arr, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$sqladd = db_array_to_insert_sqladd($arr);
	if(!$sqladd) return FALSE;
	return db_exec("REPLACE INTO {$d->tablepre}$table $sqladd", $d);
}

function db_update($table, $cond, $update, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$condadd = db_cond_to_sqladd($cond);
	$sqladd = db_array_to_update_sqladd($update);
	if(!$sqladd) return FALSE;
	return db_exec("UPDATE {$d->tablepre}$table SET $sqladd $condadd", $d);
}

function db_delete($table, $cond, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$condadd = db_cond_to_sqladd($cond);
	return db_exec("DELETE FROM {$d->tablepre}$table $condadd", $d);
}

function db_truncate($table, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	return $d->truncate($d->tablepre.$table);
}

function db_read($table, $cond, $d = NULL) {
	$db = $_SERVER['db'];
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	$sqladd = db_cond_to_sqladd($cond);
	$sql = "SELECT * FROM {$d->tablepre}$table $sqladd";
	return db_sql_find_one($sql, $d);
}

function db_find($table, $cond = array(), $orderby = array(), $page = 1, $pagesize = 10, $key = '', $col = array(), $d = NULL) {
	$db = $_SERVER['db'];
	
	// 高效写法，定参有利于编译器优化
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	return $d->find($table, $cond, $orderby, $page, $pagesize, $key, $col);
}

function db_find_one($table, $cond = array(), $orderby = array(), $col = array(), $d = NULL) {
	$db = $_SERVER['db'];
	
	// 高效写法，定参有利于编译器优化
	$d = $d ? $d : $db;
	if(!$d) return FALSE;
	
	return $d->find_one($table, $cond, $orderby, $col);
}

// 保存 $db 错误到全局
function db_errno_errstr($r, $d = NULL, $sql = '') {
	global $errno, $errstr;
	if($r === FALSE) { //  && $d->errno != 0
		$errno = $d->errno;
		$errstr = db_errstr_safe($errno, $d->errstr);
		$s = 'SQL:'.$sql."\r\nerrno: ".$errno.", errstr: ".$errstr;
		xn_log($s, 'db_error');
	}
}

// 安全的错误信息
function db_errstr_safe($errno, $errstr) {
	if(DEBUG) return $errstr;
	if($errno == 1049) {
		return '数据库名不存在，请手工创建';
	} elseif($errno == 2003 ) {
		return '连接数据库服务器失败，请检查IP是否正确，或者防火墙设置';
	} elseif($errno == 1024) {
		return lang('connect_db_fail');
	} elseif($errno == 1045) {
		return '数据库账户密码错误';
	}
	return $errstr;
}


//----------------------------------->  表结构和索引相关 end
if (!function_exists('mysql_to_unix')) {
    /**
     * Converts a MySQL Timestamp to Unix
     *
     * @param int    MySQL timestamp YYYY-MM-DD HH:MM:SS
     * @return    int    Unix timstamp
     */
    function mysql_to_unix($time = ''):int
    {
        // We'll remove certain characters for backward compatibility
        // since the formatting changed with MySQL 4.1
        // YYYY-MM-DD HH:MM:SS

        $time = str_replace(array('-', ':', ' '), '', $time);

        // YYYYMMDDHHMMSS
        return mktime(
            substr($time, 8, 2),
            substr($time, 10, 2),
            substr($time, 12, 2),
            substr($time, 4, 2),
            substr($time, 6, 2),
            substr($time, 0, 4)
        );
    }
}
/*
$cond = array('id'=>123, 'groupid'=>array('>'=>100, 'LIKE'=>'\'jack'));
$s = db_cond_to_sqladd($cond);
echo $s;

WHERE id=123 AND groupid>100 AND groupid LIKE '%\'jack%' 

// 格式：
array('id'=>123, 'groupid'=>123)
array('id'=>array(1,2,3,4,5))
array('id'=>array('>' => 100, '<' => 200))
array('username'=>array('LIKE' => 'jack'))
*/

function db_cond_to_sqladd($cond) {
	$s = '';
	if(!empty($cond)) {
		$s = ' WHERE ';
		foreach($cond as $k=>$v) {
			if(!is_array($v)) {
                if($v === null) $v = '';
                $is_str_v = is_string($v);
                if(!empty($v) && $is_str_v) $v = "'".addslashes($v)."'";
                elseif(is_bool($v)) $v = (int)$v;
				$s .= "`{$k}`={$v} AND ";
			} elseif(isset($v[0])) {
				// OR 效率比 IN 高(注：有索引时在mysql中的确如此，高版本上也不例外)
                $more_pick = (count($v) >= 32);//数量多时用IN()
				$s .= $more_pick ?  "`{$k}` IN (" : '(';
				//$v = array_reverse($v);
                foreach ($v as $v1) {
                    if($v1 === null) $v1 = '';
                    $is_str_v1 = is_string($v1);
                    if(!empty($v1) && $is_str_v1) $v1 = "'".addslashes($v1)."'";
                    elseif(is_bool($v1)) $v1 = (int)$v1;
                    $s .= $more_pick ? "{$v1}," : "`{$k}`={$v1} OR ";
                }
                $s = substr($s, 0, $more_pick ? -1 : -4);
				$s .= ') AND ';
				
				/*
				$ids = implode(',', $v);
				$s .= "$k IN ($ids) AND ";
				*/
			} else {
				foreach($v as $k1=>$v1) {
                    if($v1 === null) $v1 = '';
					if($k1 == 'LIKE') {
						$k1 = ' LIKE ';
						if(!empty($v1)) $v1="%{$v1}%";
					}
                    if(is_bool($v1)) $v1 = (int)$v1;
                    else $v1 = is_string($v1) ? "'".addslashes($v1)."'" : $v1;
					$s .= "`{$k}`{$k1}{$v1} AND ";
				}
			}
		}
		$s = substr($s, 0, -4);
	}
	return $s;
}

function db_orderby_to_sqladd($orderby) {
	$s = '';
	if(!empty($orderby)) {
		$s .= ' ORDER BY ';
		$comma = '';
		foreach($orderby as $k=>$v) {
			$s .= $comma."`$k` ".($v == 1 ? ' ASC ' : ' DESC ');
			$comma = ',';
		}
	}
	return $s;
}


/*
	$arr = array(
		'name'=>'abc',
		'stocks+'=>1,
		'date'=>12345678900,
	)
	db_array_to_update_sqladd($arr);
*/
function db_array_to_update_sqladd($arr) {
	$s = '';
	foreach($arr as $k=>$v) {
        if($v === null) $v = '';
        $is_str_v = is_string($v);
        if(!empty($v) && $is_str_v) $v = addslashes($v);
        elseif(is_bool($v)) $v = (int)$v;
		$op = substr($k, -1);
        $v = $is_str_v ? "'{$v}'" : $v;//非字符串不加引号，以减轻数据库的转换工作
		if($op == '+' || $op == '-') {
			$k = substr($k, 0, -1);
			$s .= "`{$k}`={$k}{$op}{$v},";
		} else {
			$s .= "`{$k}`={$v},";
		}
	}
	return substr($s, 0, -1);
}

/*
	$arr = array(
		'name'=>'abc',
		'date'=>12345678900,
	)
	db_array_to_insert_sqladd($arr);
*/
function db_array_to_insert_sqladd($arr) {
	$s = '';
	$keys = array();
	$values = array();
	foreach($arr as $k=>$v) {
        if($v === null) $v = '';
        $is_str_v = is_string($v);
        if(!empty($v) && $is_str_v) $v = addslashes($v);
        elseif(is_bool($v)) $v = (int)$v;
        $v = $is_str_v ? "'{$v}'" : $v;//非字符串不加引号，以减轻数据库的转换工作
		$k = addslashes($k);
		$keys[] = '`'.$k.'`';
		$values[] = $v;
	}
	$keystr = implode(',', $keys);
	$valstr = implode(',', $values);
	$sqladd = "($keystr) VALUES ($valstr)";
	return $sqladd;
}

/**
 * 获取指定功能的SQL语句
 * @param string $table 表名
 * @param string $sqltype 功能,有:自增列值,主键
 * @param string $dbtype 数据库类别
 * @return bool|string
 */
function GetDBSql(string $table, string $sqltype, $dbtype = 'mysqli')
{
    $ret = false;
    if (!empty($table)) {
        global $tablepre, $db;
        if (empty($tablepre)) $tablepre = $db->tablepre;
        $table_schema = $db->rconf['user'];
        switch (strtolower($sqltype)) {
            case 'autoincrementval':
            case 'auto_increment':
            case '自增列值':
                switch ($dbtype) {
                    case 'sqlite':
                    case 'pdo_sqlite':
                        $ret = "SELECT `seq`+1 FROM `sqlite_sequence` WHERE `name` = '{$tablepre}{$table}';";
                        break;
                    case 'pdo_mongodb'://不支持自增列值
                    case 'mongodb':
                        break;
                    case 'mysqli':
                    case 'mysql':
                    default:
                        $ret = "SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '{$tablepre}{$table}' AND TABLE_SCHEMA='{$table_schema}'";
                        break;
                }
                break;
            case 'pri':
            case 'primary key':
            case 'primary_key':
            case '主键':
                switch ($dbtype) {
                    case 'sqlite':
                    case 'pdo_sqlite':
                        $sql = "pragma table_info('{$tablepre}{$table}');";
                        $mkey = 'name';
                        $r = $db->sql_find($sql, $mkey);
                        $priName = null;
                        if (!empty($r)) {
                            foreach ($r as $name => &$fields) {
                                if ($fields['pk'] == 1) {
                                    $priName = $fields['name'];
                                    break;
                                }
                            }
                        }
                        if ($priName != null) {
                            $ret = "SELECT '{$priName}' as COLUMN_NAME;";
                        }
                        break;
                    case 'pdo_mongodb'://不支持自增列值
                    case 'mongodb':
                        break;
                    default:
                        $ret = "SELECT `COLUMN_NAME` FROM INFORMATION_SCHEMA.COLUMNS where `TABLE_NAME`='{$tablepre}{$table}' AND `table_schema` = '{$table_schema}' AND `COLUMN_KEY` = 'PRI'";
                        break;
                }
                break;
            case 'alltables':
            case '所有数据表':
                //$table参数为数据库名
                switch ($dbtype) {
                    case 'sqlite':
                    case 'pdo_sqlite':
                        $ret = "SELECT name as TABLE_NAME FROM sqlite_master WHERE type='table' ORDER BY name;";
                        break;
                    case 'pdo_mongodb'://待补充
                    case 'mongodb':
                        break;
                    default:
                        $ret = "SELECT `TABLE_NAME` FROM INFORMATION_SCHEMA.TABLES WHERE `TABLE_SCHEMA` = '{$table_schema}' AND table_type='BASE TABLE' ORDER BY TABLE_NAME;";
                        if($table != 'all' && $table != '-1' && $table != '*')
                            $ret = "SELECT `TABLE_NAME` FROM INFORMATION_SCHEMA.TABLES WHERE `TABLE_SCHEMA` = '{$table}' AND table_type='BASE TABLE' ORDER BY TABLE_NAME;";
                        break;
                }
                break;
            default:
                break;
        }
    }
    return $ret;
}
/**
 * 获取表的字段列表,字段名按mysql处理
 * @param string $table 表名,不要包含前缀
 * @param string $metadatas 要获取哪些信息,默认为COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT,空为COLUMN_NAME
 * @return array|false 如果返回值有效,则是以COLUMN_NAME为Key的数组,查询一项则返回列名数组,两项则返回列名=>第二项值,三项:列名=>数据行
 */
function &table_column_list(string $table, $metadatas = 'COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT')
{
    global $conf, $db, $tablepre;
    $retd = false;
    if (empty($table)) return $retd;
    if (empty($tablepre))
        $tablepre = $db->tablepre;
    $table_schema = $db->rconf['user'];
    $sql = null;
    $mkey = null;
    $r = null;
    $mysql_sqlite_colNames = array(
        'DATA_TYPE' => 'type',
        'COLUMN_DEFAULT' => 'dflt_value',
        'IS_NULLABLE' => 'notnull',
        'COLUMN_NAME' => 'name',
        'COLUMN_KEY' => 'pk',
    );
    switch ($conf['db']['type']) {
        case 'pdo_sqlite':
        case 'sqlite':
            foreach ($mysql_sqlite_colNames as $k => $cf) {
                $metadatas = str_ireplace($k, $cf, $metadatas);
            }
            if (empty($metadatas)) $metadatas = 'name';
            if (stripos($metadatas, 'name') < 0)
                $metadatas = 'name,' . $metadatas;
            $metadatas = explode(',', $metadatas);
            $sql = "pragma table_info('{$tablepre}{$table}');";
            $mkey = 'name';
            break;
        default:
            if (empty($metadatas)) $metadatas = 'COLUMN_NAME';
            if (stripos($metadatas, 'COLUMN_NAME') < 0)
                $metadatas = 'COLUMN_NAME,' . $metadatas;
            $sql = "SELECT {$metadatas} FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '{$tablepre}{$table}' AND table_schema = '{$table_schema}';";
            $mkey = 'COLUMN_NAME';
            break;
    }
    if (!empty($sql)) $r = $db->sql_find($sql, $mkey);
    $retd = array();
    if (!empty($r)) {
        $colCount = count(current($r));
        $arrKeys = array_keys(current($r));
        if (is_array($metadatas)) $colCount = count($metadatas);
        foreach ($r as $cn => &$coldata) {
            if ($colCount == 1) $retd[] = $cn;
            if ($colCount == 2) $retd[$cn] = $coldata[(is_array($metadatas) ? $metadatas[1] : $arrKeys[1])];
            if (count($retd) == 0) {
                $retd = &$r;
                if (!empty($mysql_sqlite_colNames)) {
                    //更换数据列名:
                    foreach ($mysql_sqlite_colNames as $k => $cf) {
                        if (isset($retd[$cf])) {
                            $retd[$k] = $retd[$cf];
                            if ($k == 'IS_NULLABLE') {//notnull => IS_NULLABLE
                                if ($retd[$k] == 0) $retd[$k] = 1;
                                else $retd[$k] = 0;
                            }
                            unset($retd[$cf]);
                        }
                    }
                } else
                    break;
            }
        }
    }
    return $retd;
}

/**
 * 删除表的字段,兼容pdo_sqlite
 * @param string $table 表名,不要包含前缀
 * @param array|string $columns 字段列表
 * @return bool
 */
function drop_table_columns(string $table, $columns)
{
    global $db, $tablepre, $conf;
    if (empty($table) || empty($columns)) return false;
    if (empty($tablepre))
        $tablepre = $db->tablepre;
    if (!is_array($columns)) {
        if (!is_string($columns)) $columns = strval($columns);
        $columns = preg_split('#[,;\\|]+#s', $columns, -1, PREG_SPLIT_NO_EMPTY);
    }
    $sql = '';
    $dbcfg = &$conf['db'];
    if ($dbcfg['type'] != 'pdo_sqlite') {
        foreach ($columns as &$column) {
            $column = trim($column, " \t\n\r\0\x0B`");
            if (!empty($column)) $sql .= ',DROP COLUMN `' . $column . '`';
        }
        if (!empty($sql))
            $sql = "ALTER TABLE `{$tablepre}{$table}` " . substr($sql, 1) . ';';
    } else {
        $data = $db->sql_find('PRAGMA table_info (\'' . $tablepre . $table . '\')');
        if (!empty($data)) {
            foreach ($columns as &$column) {
                $column = trim($column, " \t\n\r\0\x0B`");
            }
            $fields = '';//字段列表
            $pkey = '';//主键
            foreach ($data as &$_da) {
                if (!in_array($_da['name'], $columns)) {
                    $fields .= ',' . $_da['name'];
                    if (!empty($_da['pk']))
                        $pkey = $_da['name'];
                }
            }
            if (!empty($fields)) {
                $fields = substr($fields, 1);
                if (!empty($pkey)) $pkey = "CREATE UNIQUE INDEX uk_key on \"{$tablepre}{$table}\"(\"$pkey\");";
                $sql = "PRAGMA foreign_keys = 0;
BEGIN TRANSACTION;
ALTER TABLE \"{$tablepre}{$table}\" RENAME TO sqlitemanager_temp_table_ghx;
CREATE TABLE \"{$tablepre}{$table}\" AS SELECT {$fields} FROM sqlitemanager_temp_table_ghx;
DROP TABLE sqlitemanager_temp_table_ghx;
{$pkey}
COMMIT;
PRAGMA foreign_keys = 1;";
            }
        }
    }
    return db_exec($sql);
}

function __ddl_to_sqladd(array $ddl)
{
    $ccs = count($ddl);
    if ($ccs < 2) return false;
    $colname = (empty($ddl['name']) ? $ddl[0] : $ddl['name']);
    $colattr = (empty($ddl['attr']) ? $ddl[1] : $ddl['attr']);
    if (stripos($colattr, ' NULL') < 5)
        $colattr .= ' NOT NULL';
    $comment = '';
    if ($ccs > 2)
        $comment = ' COMMENT \'' . addcslashes(empty($ddl['comment']) ? $ddl[2] : $ddl['comment'], "\0\r\n\t\f\v'") . '\'';
    $default = stripos($colattr, 'int') !== FALSE ? "'0'" : "''";
    $sqladd = "{$colname} {$colattr} DEFAULT {$default}{$comment}";
    return $sqladd;
}

/**
 * 向数据表中添加字段
 * @param string $table 表名,不要包含前缀
 * @param array $ddls 字段数据数组,可以是多组,包含的元素有:name,attr,comment?,也可能是0,1,2?
 * @return bool 是否成功
 */
function add_table_columns(string $table, array $ddls)
{
    global $db, $tablepre;
    $depth = array_depth($ddls);
    if ($depth == 0) return false;
    if (empty($tablepre))
        $tablepre = $db->tablepre;
    if ($depth == 1)
        $ddl = array($ddls);
    $sql = '';
    foreach ($ddls as &$ddl) {
        $sqladd = __ddl_to_sqladd($ddl);
        $sql .= ',ADD COLUMN ' . $sqladd;
    }
    if (!empty($sql)) {
        $sql = "ALTER TABLE {$tablepre}{$table} " . substr($sql, 1) . ';';
        return db_exec($sql);
    }
    return false;
}
/**
 * 对SQL语句中的字段注释进行转换
 * @param string|string[] $sql sql语句
 * @param string $dbtype 数据库类型
 * @return string|string[]|null
 */
function &FixSqlFieldComment($sql, $dbtype)
{
    if (!empty($sql)) {
        $reg = '';
        $rep = '';
        switch ($dbtype) {
            case 'sqlite':
            case 'pdo_sqlite':
                $reg = '#\bCOMMENT\s+([\'"])(.*?)\1(?<!\\\1)#isu';
                $rep = '/*$2*/';
                break;
            case 'mysql':
            case 'mysqli':
            case 'pdo_mysql':
                $reg = '/\s+(\-\-|#)\s*(.*)$/iu';
                $rep = ' COMMENT \'$2\'';
                break;
            default:
                break;
        }
        if (!empty($reg)) {
            $count = 0;
            $sql = preg_replace($reg, $rep, $sql, -1, $count);
        }
    }
    return $sql;
}
/**
 * 安全过滤类-对进入的数据加下划线 防止SQL注入
 * @param string|string[] $value 需要过滤的值
 * @param mixed $type $value的类型,值(0),字段名(1)之类
 * @return string|string[]
 */
function fliter_sql($value, $type = 0)
{
    $sql = array("select", 'insert', "update", "delete", "\'", "\/\*", "\.\.\/", "\.\/", "union", "into", "load_file", "outfile", 'exec');
    $sql_re = array("_select", "_insert", "_update", "_delete", "", "", "", "", "_union", "_into", "_load_file", "_outfile", '_exec');
    switch ($type) {
        case 0:
        case 'value':
            break;
        case 1:
        case 'field':
            array_push($sql, '"', '`', "\0", '&');
            array_push($sql_re, '', '', '', '');
            break;
        default:
            break;
    }
    return str_replace($sql, $sql_re, $value);
}

?>